#if !SERVER
using ActorSystem;
using GameDesigner;
using Net.Client;
using Net.Component;
using Net.Share;
using System.Security.Principal;
using UnityEngine;

namespace Example2
{
    public abstract partial class Actor : ActorBase<Actor, NormalProperty, SkillBase<Actor, BuffBase<Actor>>, BuffBase<Actor>>
    {
        public bool IsLocal => Identity == ClientBase.Instance.UserId;
        internal HeadBloodBar headBloodBar;
        public Vector3 headBarOffset = new(0, 1f, 0);
        public StateController controller;

        public override void OnOperation(in Operation opt)
        {
            switch (opt.cmd)
            {
                case Command.EnterArea:
                    EnterArea(opt);
                    break;
                case Command.ExitArea:
                    ExitArea(opt);
                    break;
                case Command.SyncPosition:
                    SyncPosition(opt);
                    break;
                case Command.SwitchState:
                    SwitchState(opt);
                    break;
                case Command.Fire:
                    Fire(opt);
                    break;
                case Command.Resurrection:
                    Resurrection(opt);
                    break;
                case Command.Damage:
                    OnDamage(null, opt.index);
                    break;
                default:
                    base.OnOperation(opt);
                    break;
            }
        }

        public virtual void OnDamage(Actor target, int damage)
        {
            var flyingWord = Object.Instantiate(GameManager.I.flyingWord, GameManager.I.UIRoot);
            flyingWord.text.text = damage.ToString();
            flyingWord.position = transform.Position + new Vector3(0, 0.5f, 0);
            UpdateBloodBar();
        }

        public void UpdateBloodBar()
        {
            headBloodBar.text.text = $"{Property.Health}/{Property.HealthMax}";
            headBloodBar.image.fillAmount = (float)Property.Health / Property.HealthMax;
        }

        public virtual void Resurrection(in Operation opt)
        {
        }

        public virtual void Fire(in Operation opt)
        {
        }

        private void SwitchState(in Operation opt)
        {
            controller.ChangeState(opt.index, opt.index1, false, 0);
        }

        protected virtual void EnterArea(in Operation opt)
        {
            var viewPrefab = GetViewPrefab();
            View = Object.Instantiate(viewPrefab);
            View.Actor = this;
            View.transform.SetPositionAndRotation(opt.position, opt.rotation);
            View.gameObject.SetActive(true);
            if (opt.identity == ClientBase.Instance.UserId)
            {
                View.name = ClientBase.Instance.UserId.ToString();
                Camera.main.GetComponent<SimpleCameraController>().target = View.transform;
            }
        }

        protected abstract ActorView GetViewPrefab();

        private void ExitArea(in Operation opt)
        {
            View.gameObject.SetActive(false);
        }

        private void SyncPosition(in Operation opt)
        {
            transform.SetPositionAndRotation(opt.position, opt.rotation);
        }

        public override void OnUpdate()
        {
            if (View == null)
                return;
            View.transform.position = Vector3.Lerp(View.transform.position, transform.Position, 0.25f);
            View.transform.rotation = Quaternion.Lerp(View.transform.rotation, transform.Rotation, 0.25f);
        }

        public override void AddOperation(in Operation opt)
        {
            if (IsLocal)
                ClientBase.Instance.AddOperation(opt);
        }
    }
}
#endif